/**
 * 使用 Mersenne Twister 在 C++ 中生成随机数
 *   32位PRNG将生成0-4,294,967,296
 * 
 * 使用 Mersenne Twister 掷骰子
 * 
 * 最佳实践
 *   仅给给定的伪随机数生成器播种一次，并且不重新播种。
 * 
 */

#include <iostream>
#include <random> // for std::mt19937
#include <chrono> // for std::chrono
#include <map>

int main()
{
	std::mt19937 mt{}; // Instantiate a 32-bit Mersenne Twister

	// Print a bunch of random numbers
	for (int count{ 1 }; count <= 40; ++count)
	{
		std::cout << mt() << '\t'; // generate a random number

		// If we've printed 5 numbers, start a new row
		if (count % 5 == 0)
			std::cout << '\n';
	}



    
    std::cout << "=========================================\n";
    std::mt19937 mt2{};
    // Create a reusable random number generator that generates uniform numbers between 1 and 6
	std::uniform_int_distribution<> die6_a{ 1, 6 }; // for C++14, use std::uniform_int_distribution<> die6{ 1, 6 };

	// Print a bunch of random numbers
	for (int count{ 1 }; count <= 40; ++count)
	{
        int res = die6_a(mt2);
		std::cout << res << '\t'; // generate a roll of the die here

		// If we've printed 10 numbers, start a new row
		if (count % 10 == 0) {
			std::cout << '\n';
        }

        
	}



    std::cout << "=========================================\n";
    std::map<int, int> resultMap {};
    // Seed our Mersenne Twister using steady_clock
	std::mt19937 mt3{ static_cast<std::mt19937::result_type>(
		std::chrono::steady_clock::now().time_since_epoch().count()
		) };

	// Create a reusable random number generator that generates uniform numbers between 1 and 6
	std::uniform_int_distribution<> die6_b{ 1, 6 }; // for C++14, use std::uniform_int_distribution<> die6{ 1, 6 };

	// Print a bunch of random numbers
	for (int count{ 1 }; count <= 400000; ++count)
	{
        int res = die6_b(mt3);
		std::cout << res << '\t'; // generate a roll of the die here

		// If we've printed 10 numbers, start a new row
		if (count % 10 == 0) {
			std::cout << '\n';
        }

        if (resultMap.find(res) == resultMap.end()) {
            resultMap[res] = 1;
        } else {
            resultMap[res]++;
        }
	}
    std::cout << "=========================================\n";
    for (std::map<int, int>::iterator it = resultMap.begin(); it != resultMap.end(); ++it) {
        int key = it->first;
        std::cout << key << ": " << it->second << "\n";
    }


	return 0;
}